﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Drawing;
using CoyoEden.Web.Data;

namespace CoyoEden.Web.HttpHandlers
{
	/// <summary>
	/// SWFUpload handler
	/// </summary>
	public class SWFUploadHandler : IHttpHandler
	{
		#region IHttpHandler Members

		public bool IsReusable
		{
			get { return true; }
		}

		public void ProcessRequest(HttpContext context)
		{
			var _params = new Params(context);
			RequestParams = _params;
			var response = "dummy response";
			FileRelativeFolder = string.Format("{0}/{1}/{2}/", context.User.Identity.Name, DateTime.Now.Year, DateTime.Now.Month);
			FileRelativeFullFolder = string.Format("{0}{1}/{2}", Utils.RelativeWebRoot, "App_Data/files", FileRelativeFolder);
			FeedbackData data = new FeedbackData();

			switch (_params.Flag) { 
				case "fileupload":
					data.IsOk = true;
					data.Body = _params.CurrentSessionID;
					data.Context.Add("user",_params.UserID);
					break;
				case "category":
					//Upload images to a certain category
					UploadToCategory(context, out data);
					break;
				case "post":
					//upload files to a post or a page
					break;
				case "album":
					//upload images to a certain album
					UploadToAlbum(context,out data);
					break;
				case "community":
					//upload icon for a community
					UploadToCommunity(context, out data);
					break;
			}
			response = Utils.ToStr<FeedbackData>(data);
			context.Response.Clear();
			context.Response.ContentType = "application/json;charset=utf-8";
			context.Response.Write(response);
			context.Response.End();
		}
		#endregion

		#region helper methods
		private void UploadToAlbum(HttpContext context, out FeedbackData msg)
		{
			msg = new FeedbackData();
			HttpPostedFile file = context.Request.Files["FileData"];

			var fileExt = file.FileName.Substring(file.FileName.LastIndexOf("."));
			var fileName = string.Format("{0}{1}", Utils.RandomFileName(), fileExt);

			Upload(context, true,fileName, out msg);

			FileAbsoluteUrl = string.Format("{0}image.axd?picture={1}", Utils.AbsoluteWebRoot, FileRelativeFolder + fileName);
			msg.Context.Add("ImgSrc", FileAbsoluteUrl);
			msg.Context.Add("callback", "parent.AlbumPicList.UploadOkCallback");//We raise the swfupload control through an iframe,the UploadOkCallback function was defined in the parent page.

		}
		private void UploadToCategory(HttpContext context,out FeedbackData msg) {
			msg = new FeedbackData();
			HttpPostedFile file = context.Request.Files["FileData"];
			try {
				var fileExt = file.FileName.Substring(file.FileName.LastIndexOf("."));
				var fileName = string.Format("ICONCATEGORY{0}{1}",RequestParams.FlagValue,fileExt);
				using(Image rawImg=Image.FromStream(file.InputStream)){
					Bitmap img= Utils.GenAThumbnail(file, RequestParams.ImgSize, RequestParams.ImgSize);
					Utils.Upload(context.Server,FileRelativeFullFolder,img,rawImg.RawFormat,fileName);
					img.Dispose();
				}
				FileAbsoluteUrl = string.Format("{0}image.axd?picture={1}", Utils.AbsoluteWebRoot, FileRelativeFolder + fileName);
				msg.Context.Add("ImgSrc",FileAbsoluteUrl);
				msg.Context.Add("callback","parent.Category.UploadOkCallback");//We raise the swfupload control through an iframe,the UploadOkCallback function was defined in the parent page.

			}catch(Exception ex){
				msg.IsOk = false;
				msg.Body = "上传分类图片时发生例外";
				msg.Context.Add("error",ex.Message);
			}
		}
		private void UploadToCommunity(HttpContext context,out FeedbackData msg) {
			msg = new FeedbackData();
			HttpPostedFile file=context.Request.Files["FileData"];
			try
			{
				var fileExt = file.FileName.Substring(file.FileName.LastIndexOf("."));
				var fileName = string.Format("ICONCOMMUNITY{0}{1}", RequestParams.FlagValue,fileExt);
				using (Image rawImg = Image.FromStream(file.InputStream))
				{
					Bitmap img = Utils.GenAThumbnail(file, RequestParams.ImgSize, RequestParams.ImgSize);
					Utils.Upload(context.Server, FileRelativeFullFolder, img, rawImg.RawFormat, fileName);
					img.Dispose();
				}
				FileAbsoluteUrl = string.Format("{0}image.axd?picture={1}", Utils.AbsoluteWebRoot, FileRelativeFolder + fileName);
				msg.Context.Add("ImgSrc", FileAbsoluteUrl);
				msg.Context.Add("callback", "parent.Community.UploadOkCallback");//We raise the swfupload control through an iframe,the UploadOkCallback function was defined in the parent page.

			}
			catch (Exception ex)
			{
				msg.IsOk = false;
				msg.Body = "上传社区图标时发生例外";
				msg.Context.Add("error", ex.Message);
			}
		}
		private void Upload(HttpContext context,string filename,out FeedbackData msg)
		{
			msg = new FeedbackData();
			HttpPostedFile file = context.Request.Files["FileData"];
			try {
				Utils.Upload(context.Server, FileRelativeFullFolder, file,filename);
			}
			catch (Exception ex) {
				msg.IsOk = false;
				msg.Body = "上传图片时发生例外";
				msg.Context.Add("error",ex.Message);
			}
		}

		private void Upload(HttpContext context, bool autoThumbnail,string filename,out FeedbackData msg)
		{
			msg=new FeedbackData();
			HttpPostedFile file = context.Request.Files["FileData"];

			if (!autoThumbnail) return;
			int dotIndex = filename.LastIndexOf(".");
			string fileExtentsion = filename.Substring(dotIndex + 1);
			string fileNameNoExt = filename.Substring(0, dotIndex);
			//automatically generate thumbnail for images
			//size1:300x180,size2:150x150.
			//ToDo:Sizes should be configable
			try
			{
				using (System.Drawing.Image rawImg = System.Drawing.Image.FromStream(file.InputStream))
				{
					Bitmap thumbnail1 = Utils.GenAThumbnail(rawImg, 80, 80, false);
					if (rawImg.Width > MaxImgSize || rawImg.Height > MaxImgSize)
					{
						Bitmap thumbnail2 = Utils.GenAThumbnail(rawImg, MaxImgSize, MaxImgSize, false);
						Utils.Upload(context.Server, FileRelativeFullFolder, thumbnail2, rawImg.RawFormat, filename);
					}
					else {
						Utils.Upload(context.Server, FileRelativeFullFolder, file,filename);
					}
					Utils.Upload(context.Server, FileRelativeFullFolder, thumbnail1, rawImg.RawFormat, string.Format("{0}_{1}.{2}", fileNameNoExt, "80x80", fileExtentsion));

				}
			}
			catch (Exception ex) {
				msg.IsOk = false;
				msg.Body = "上传图片时发生例外";
				msg.Context.Add("error", ex.Message);
			}
		}
		#endregion

		#region member variables
		/// <summary>
		/// Category icon file relative folder
		/// </summary>
		/// <remarks>Format:"user1/2008/7/"</remarks>
		public string FileRelativeFolder { get; set; }
		/// <summary>
		/// Category icon file url,EG.:"Http://xxxxx/App_Data/user1/2008/7/xx.jpg"
		/// </summary>
		public string FileAbsoluteUrl { get; set; }
		/// <summary>
		/// File relative full folder path.E.g:wwwRoot/App_Data/User1/2008/7/xx.jpg
		/// </summary>
		public string FileRelativeFullFolder { get; set; }
		/// <summary>
		/// Request params
		/// </summary>
		Params RequestParams { get; set; }
		public int MaxImgSize { get { return 1024; } }
		#endregion

		#region data of the request
		struct Params {

			#region member variables
			private string _CurrentSessionID;
			/// <summary>
			/// Current Session id
			/// </summary>
			public string CurrentSessionID
			{
				get {
					return _CurrentSessionID;
				}
			}
			private string _Flag;
			/// <summary>
			/// Flag
			/// </summary>
			public string Flag {
				get { return _Flag; }
			}
			public string _FlagValue;
			/// <summary>
			/// Flag's value
			/// </summary>
			public string FlagValue {
				get { return _FlagValue; }
			}
			private string _UserID;
			/// <summary>
			/// Current UserID
			/// </summary>
			public string UserID {
				get { return _UserID; }
			}
			private int _ImgSize;
			/// <summary>
			/// Img size.If the user upload a img
			/// </summary>
			public int ImgSize {
				get { return _ImgSize; }
			}
			#endregion

			public Params(HttpContext context) {
				var request = context.Request;
				_CurrentSessionID = request["ASPSESSID"];
				_Flag = request["flag"];
				_FlagValue=request["flagValue"];
				_ImgSize = string.IsNullOrEmpty(request["imgsize"]) ? 80 : Convert.ToInt32(request["imgsize"]);
				_UserID = string.IsNullOrEmpty(request["userid"]) ? "_UNKNOWN_" : request["userid"];
			}
		}
		#endregion
	}
}
